package com.ht.modules.system.quartz.job;

import com.ht.modules.system.quartz.service.IQuartzJobService;
import com.ht.modules.system.util.ZipMultiFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
public class MysqlBackJob implements Job {
    @Autowired
    @Lazy
    IQuartzJobService quartzJobService;
    @Autowired
    Environment env;
    @Autowired
    private ZipMultiFile zipMultiFile;

    @Value(value = "${dbBack.mysql-back-url}")
    private String mysqlBackUrl;
    @Value(value = "${dbBack.is-docker-install}")
    private Boolean isDockerInstall;
    @Value(value = "${dbBack.mysql-back-docker-url}")
    private String mysqlBackDockerUrl;


    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        quartzJobService.authCheck();
        if (Strings.isBlank(mysqlBackUrl)) {
            throw new RuntimeException("缺少数据库备份配置信息！");
        }
        if (null == isDockerInstall) {
            throw new RuntimeException("缺少数据库备份配置信息！");
        }
        if (isDockerInstall) {
            if (Strings.isBlank(mysqlBackDockerUrl)) {
                throw new RuntimeException("缺少数据库备份配置信息！");
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
        Date date = new Date();
        String osName = System.getProperty("os.name").toLowerCase().replaceAll("\\s", "");
        String database = "enroll";
        String fileName = database + sdf.format(date) + ".sql";
        String fileUrl = "";
        String backFileUrl = mysqlBackUrl + File.separator + fileName;

        File zipFile = new File(mysqlBackUrl + File.separator + database + sdf.format(date) + ".zip");
        File fileParent = new File(zipFile.getParent());
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        if (zipFile.exists()) {
            zipFile.delete();
        }
        List<File> fileList = new ArrayList<File>();
        fileUrl = mysqlBackUrl + File.separator + fileName;
        if (isDockerInstall) {
            fileUrl = mysqlBackDockerUrl + File.separator + fileName;
        }

        File oldBackFile = new File(backFileUrl);
        if (oldBackFile.exists()) {
            oldBackFile.delete();
        }
        String user = env.getProperty("spring.datasource.dynamic.datasource.master.username");
        String password = env.getProperty("spring.datasource.dynamic.datasource.master.password");
        StringBuilder cmd = new StringBuilder();

        // DOCKER容器备份命令：docker exec mysql sh -c 'exec mysqldump pro -uroot -pmysql-XXXX > /var/lib/mysql/mysql-files/pro.sql'
        // window备份命令： mysqldump pro -uroot -pXXXX > D:\pro.sql
        if (osName.contains("win")) {
            // Windows系统
            cmd.append(" mysqldump ").append(database).append(" -u").append(user).append(" -p").append(password).append(" >").append(fileUrl);
        } else if (osName.contains("nix") || osName.contains("nux")) {
            // Linux操作系统
            cmd.append("docker exec mysql sh -c 'exec mysqldump ").append(database).append(" -u").append(user).append(" -p").append(password).append(" >").append(fileUrl).append("'");
        }
        try {
            String[] sysCmd;
            if (osName.contains("win")) {
                // Windows系统
                sysCmd = new String[]{"cmd", "/c", cmd.toString()};
            } else if (osName.contains("nix") || osName.contains("nux")) {
                // Linux操作系统
                sysCmd = new String[]{"/bin/sh", "-c", cmd.toString()};
            } else {
                throw new RuntimeException("当前为未知系统！");
            }
            // 创建一个线程去执行
            Process proc = Runtime.getRuntime().exec(sysCmd);
            proc.waitFor();
            File backFile = new File(backFileUrl);
            if (!backFile.exists()) {
                throw new RuntimeException("备份数据库失败");
            } else {
                fileList.add(backFile);
            }
            proc.destroy();

            // 将文件打包
            zipMultiFile.zipFiles(fileList, zipFile);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("备份数据库失败");
        } finally {
            for (File eMap : fileList) {
                eMap.delete();
            }
        }
    }


}
